<template>
  <div class="full-height bg-white page-content content" style="padding-bottom: 20px;overflow: hidden">
    <!-- 搜索区 -->
    <ListSearch :connect-status="connectStatus" @resetSearch="resetSearch" @searchList="searchList" ref="listSearch"/>

    <!-- 操作 -->
    <div style="display: flex;padding:0 20px;margin-bottom: 10px;flex: 0" class="form-inline">
      <q-btn
        class="btn margin-r-10"
        outline
        color="primary"
        @click="quickSetup"
        label="网关初始化"
      />
      <q-btn
        class="btn margin-r-10"
        outline
        color="primary"
        @click="patchCreate"
        label="批量新建网关"
      />
    </div>

    <!-- 详情card -->
    <ListCard :connectStatusObj="connectStatusObj" style="flex: 1;margin: 0 10px" :cardInfo="cardInfo"  @deleteSuccess="deleteSuccess" />

    <gateway-dialog v-if="controllerType==='1'" :products-cnc="productsCnc" :products="products" ref="gatewayDialog" :controllerType="controllerType" @successAll="successAll" />

    <plc-dialog v-if="controllerType==='2'" :products="products" ref="plcDialog" :controllerType="controllerType" @successAll="successAll" @close="successAll"></plc-dialog>

    <!-- 选择配置类型的dialog -->
    <q-dialog class="add-edit-station-dialog dialog" v-model="configDialog">
      <q-card>
        <!-- dialog title -->
        <q-card-section class="dialog-title">
          <q-btn
            style="font-size: 18px;color: #333333"
            flat round dense
            class="iconfont icontubiao-67 close-btn dialog"
            @click="configDialog = false"
          >
          </q-btn>
        </q-card-section>

        <div style="margin: 0 70px 30px 70px">
          <div class="margin-b-20">
            <q-btn class="btn" unelevated  color="primary" label="快速设置" @click="quickSetup" style="width: 130px"/>
          </div>

          <div>
            <q-btn class="btn" unelevated color="primary" disable label="专业设置" @click="searchList" style="width: 130px"/>
          </div>
        </div>
      </q-card>
    </q-dialog>
    <!-- 控制器类型 -->
    <ControllerDialog ref="controllerDialog" @changeType="changeType"/>

    <PatchCreateGateway ref="patchCreateDialog" @success="searchList"></PatchCreateGateway>
  </div>
</template>

<script>
import ListSearch from './components/list-components/list-search'
import ListCard from './components/list-components/list-card'
import GatewayDialog from './components/list-components/gateway-dialog/index'
import PatchCreateGateway from './components/list-components/patch-create-gateway'
import { boxQueryList, getBoxProducts } from '../../boot/miot/list'
import refreshMixin from '../../assets/js/refresh-mixin'
import { mapGetters } from 'vuex'
import ControllerDialog from './components/list-components/gateway-dialog/controller-dialog'
import PlcDialog from './components/list-components/plc-dialog'
import { getPlcProducts } from '../../boot/miot/plc-list'

export default {
  name: 'miot-list',
  mixins: [refreshMixin],
  components: {
    ListSearch,
    ListCard,
    GatewayDialog,
    ControllerDialog,
    PlcDialog,
    PatchCreateGateway
  },
  data () {
    return {
      params: {
        boxId: null,
        deviceIds: null,
        startDate: null,
        endDate: null,
        schemeId: null,
        schemeLevel: null,
        connectStatus: null,
        startLastOnlineTime: null,
        endLastOnlineTime: null
      },
      queryParams: null,
      cardInfo: [],
      configDialog: false,
      controllerType: '',
      connectStatus: [{ label: '全部', value: null }, { label: '未激活', value: 'inactivated' }, { label: '在线', value: 'online' }, { label: '离线', value: 'offline' }],
      subscribeOptions: [], // 所有订阅的list
      products: [],
      productsCnc: []
    }
  },
  created () {
    this.searchList()
    this.getBoxProducts()
    this.getPlcProductInfo()
  },
  computed: {
    ...mapGetters([
      'client',
      'userInfo'
    ]),
    connectStatusObj () {
      const obj = {}
      this.connectStatus.forEach(item => {
        obj[item.value] = item.label
      })
      return obj
    }
  },
  methods: {
    refreshInfo () {
      this.$q.loading.show()
      this.searchList().then().finally(() => {
        this.$q.loading.hide()
      })
    },
    // 重置
    resetSearch () {
      this.queryParams = null
    },

    /**
     * 初始化websocket
     */
    async initWebSocket (boxId) {
      this.$nextTick(() => {
        // 如果没有获取到client，那么初始化没有执行完，等一会再执行
        if (!this.client) {
          setTimeout(() => {
            this.initWebSocket(boxId)
          }, 1000)
          return
        }
        if (this.client.connected) {
          this.onDeviceStatus(boxId)
          this.onDeviceState(boxId)
        } else {
          console.log('websocket未连接')
        }
      })
    },

    unsubscribeWebSocket () {
      // 全部取消订阅
      this.subscribeOptions.forEach(item => {
        item.unsubscribe()
      })
      // 清空订阅列表
      this.subscribeOptions = []
    },

    /**
     * 订阅设备在线状态, 在线 or 离线
     * @param boxId
     */
    onDeviceStatus (boxId) {
      const subscription = this.client.subscribe(
        `/topic/deviceStatus/update/${boxId}`,
        (message) => {
          try {
            // 获取boxId
            const boxId = message.headers.destination.split('/')[4]
            if (!boxId) return
            const ret = JSON.parse(message.body)
            // 获取推送的新的状态
            const newStatus = ret.data.status
            // 如果获取到了的话
            if (newStatus) {
              // 获取index
              const index = this.cardInfo.findIndex(item => item.boxId === boxId)
              // 设置新的状态
              if (index > -1) {
                this.cardInfo[index].onLineStatus = newStatus
              }
            }
          } catch (e) {
            console.log('解析socket订阅设备在线状态错误' + e)
          }
        }
      )
      this.subscribeOptions.push(subscription)
    },

    /**
     * 订阅设备状态
     * @param boxId 正常 or 故障
     */
    onDeviceState (boxId) {
      const subscription = this.client.subscribe(
        `/topic/deviceData/deviceState/${boxId}`,
        (message) => {
          try {
            // 获取boxId
            const boxId = message.headers.destination.split('/')[4]
            if (!boxId) return
            const ret = JSON.parse(message.body)
            // 获取推送的新的状态
            const runState = ret.data.runState
            // 如果获取到了的话
            if (runState === 0 || runState === 1) {
              // 获取index
              const index = this.cardInfo.findIndex(item => item.boxId === boxId)
              // 设置新的状态
              if (index > -1) {
                this.cardInfo[index].boxStatus = runState === 0 ? 'Normal' : 'Abnormal'
              }
            }
          } catch (e) {
            console.log('解析socket设备状态错误' + e)
          }
        }
      )
      this.subscribeOptions.push(subscription)
    },

    // 查询
    async searchList (queryParams) {
      this.$q.loading.show()
      if (queryParams) {
        this.queryParams = queryParams
        this.params.boxId = queryParams.gateWayId
        this.params.deploymentStatus = queryParams.deploymentStatus
        this.params.onLineStatus = queryParams.onLineStatus
        this.params.deviceIds = queryParams.assetNum
        this.params.startDate = queryParams.date[0]
        this.params.endDate = queryParams.date[1]
        this.params.startLastOnlineTime = queryParams.lastOnlineTime[0]
        this.params.endLastOnlineTime = queryParams.lastOnlineTime[1]
        this.params.schemeId = queryParams.position.id
        this.params.schemeLevel = queryParams.position.level
        this.params.connectStatus = queryParams.connectStatus
      }
      try {
        const { data } = await boxQueryList(this.params)
        if (data && data.list && data.list.length > 0) {
          data.list.forEach(item => {
            // 拼接子设备，用/分割
            let assetNums = ''
            if (item.deviceInfo && item.deviceInfo.length > 0) {
              item.deviceInfo.forEach((v, index) => {
                assetNums += v.assetNum
                if (index !== item.deviceInfo.length - 1) assetNums += '/'
              })
            }
            item.assetNums = assetNums
            item.prodId = this.getProdId(item.boxId)
          })
          this.cardInfo = data.list
          // 在这里循环 是因为 如果连接不上socket，不会影响下面的数据显示
          data.list.forEach(item => {
            this.unsubscribeWebSocket()
            this.initWebSocket(item.boxId)
          })
        } else {
          this.cardInfo = []
        }
      } catch (e) {
      }
      this.$q.loading.hide()
    },

    // 获取显示的prodid
    getProdId (boxId) {
      if (!boxId) return '---'
      try {
        const data = boxId.split('_')
        if (data.length === 1) return data[0]
        if (data.length === 2) return data[1]
      } catch (e) {
        return '---'
      }
    },
    // 网关初始化
    initGateWay () {
      this.configDialog = true
    },

    // 快速设置
    quickSetup () {
      this.$refs.controllerDialog.showDialog()
    },

    async getBoxProducts () {
      const { data } = await getBoxProducts()
      if (data && data.products) {
        this.productsCnc = data.products
      }
    },
    // 获取产品列表
    async getPlcProductInfo () {
      const { data } = await getPlcProducts()
      if (data?.length) {
        this.products = data
      }
    },

    // 批量创建
    patchCreate () {
      this.$refs.patchCreateDialog.showDialog()
    },

    // 所有配置全部完成
    successAll () {
      this.searchList(this.queryParams)
      this.$refs.listSearch.getDeviceNumWithBox()
    },

    // 删除成功
    deleteSuccess () {
      this.searchList(this.queryParams)
      this.$refs.listSearch.getDeviceNumWithBox()
    },

    /**
     * 更改类型
     * @param val
     */
    changeType (val) {
      this.controllerType = val
      // 类型1:CNC、类型2:PLC
      this.$nextTick(() => {
        if (val === '1') {
          // this.getBoxProducts()
          this.$refs.gatewayDialog.showDialog()
        } else if (val === '2') {
          // this.getPlcProductInfo()
          this.$refs.plcDialog.showDialog()
        }
        this.configDialog = false
      })
    }
  },
  beforeDestroy () {
    this.unsubscribeWebSocket()
  }
}
</script>
